<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue.js"></script>

</head>

<body>
    <!-- 使用 JavaScript 表达式

        迄今为止，在我们的模板中，我们一直都只绑定简单的属性键值。
        但实际上，对于所有的数据绑定，Vue.js 都提供了完全的 JavaScript 表达式支持。

        {{ number + 1 }}

        {{ ok ? 'YES' : 'NO' }}

        {{ message.split('').reverse().join('') }}

        <div v-bind:id="'list-' + id"></div>

        这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。
        有个限制就是，每个绑定都只能包含单个表达式，所以下面的例子都不会生效。

        这是语句，不是表达式
            {{ var a = 1 }}

        流控制也不会生效，请使用三元表达式 
        {{ if (ok) { return message } }}
    
        模板表达式都被放在沙盒中，只能访问全局变量的一个白名单，如 Math 和 Date 。
        你不应该在模板表达式中试图访问用户定义的全局变量。
    -->
    <div id="app">
        <!-- 模板内的表达式非常便利，但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护 -->
        不推荐在模板字符串中放入逻辑过于复杂代码，如：{{ message.split('').reverse().join('') }}
    </div>

    <div id="app2">
        {{reverseMessage}}<br> {{reverseString()}}
    </div>

    <div id="app3">
        计算属性：{{computedNow}}<br> 方法{{methodsNow()}}<br>监听：{{now}}
    </div>
</body>
<script>
    new Vue({
        el: app,
        data: {
            message: "hello,runoob,this is Vue"
        }
    })

    new Vue({
            el: "#app2",
            data: {
                message: "hello,runoob,this is Vue",
                message2: "come on,choose me",
            },
            methods: { //方法
                reverseString: function() {
                    return this.message2.split('').reverse().join('');
                }
            },
            computed: { //计算方法  --基于缓存
                reverseMessage: function() {
                    return this.message.split('').reverse().join('');
                }
            }
        })
        // 我们可以将同一函数定义为一个方法而不是一个计算属性。
        // 两种方式的最终结果确实是完全相同的。
        // 然而，不同的是计算属性是基于它们的响应式依赖进行缓存的。
        // 只在相关响应式依赖发生改变时它们才会重新求值。
        // 这就意味着只要 message 还没有发生改变，
        // 多次访问 reversedMessage 计算属性会立即返回之前的计算结果，而不必再次执行函数。

    let vm = new Vue({
        el: app3,
        data: {
            now: Date.now()
        },
        //Date.now() 不是响应式依赖：所以不会自动更新
        methods: {
            methodsNow: function() {
                return Date.now()
            }
        },
        computed: {
            computedNow: function() {
                return Date.now()
            }
        }
    })

    vm.$watch('now', function(newVal) {
            this.now = newVal
        })
        /**
            相比之下，每当触发重新渲染时，调用方法将总会再次执行函数。

            我们为什么需要缓存？
            假设我们有一个性能开销比较大的计算属性 A，它需要遍历一个巨大的数组并做大量的计算。
            然后我们可能有其他的计算属性依赖于 A 。
            如果没有缓存，我们将不可避免的多次执行 A 的 getter！如果你不希望有缓存，请用方法来替代。
        */
</script>

</html>